package com.agile.leetcode.order.timewheel;

import io.netty.util.HashedWheelTimer;
import io.netty.util.Timer;

import java.util.concurrent.TimeUnit;

/**
 * 时间轮算法可以类比于时钟，如上图箭头（指针）按某一个方向按固定频率轮动，每一次跳动称为一个 tick。这样可以看出定时轮由个3个重要的属性参数，
 * ticksPerWheel（一轮的tick数），tickDuration（一个tick的持续时间）以及 timeUnit（时间单位），
 * 例如当ticksPerWheel=60，tickDuration=1，timeUnit=秒，这就和现实中的始终的秒针走动完全类似了。
 * <p>
 * 如果当前指针指在1上面，我有一个任务需要4秒以后执行，那么这个执行的线程回调或者消息将会被放在5上。
 * 那如果需要在20秒之后执行怎么办，由于这个环形结构槽数只到8，如果要20秒，指针需要多转2圈。位置是在2圈之后的5上面（20 % 8 + 1）
 * 优缺点
 * <p>
 * 优点:效率高,任务触发时间延迟时间比delayQueue低，代码复杂度比delayQueue低。
 * <p>
 * 缺点:
 * <p>
 * (1)服务器重启后，数据全部消失，怕宕机
 * <p>
 * (2)集群扩展相当麻烦
 * <p>
 * (3)因为内存条件限制的原因，比如下单未付款的订单数太多，那么很容易就出现OOM异常
 *
 * @Author:ChenZhangKun
 * @Date: 2021/9/15 10:28
 */
public class Client {
    public static void main(String[] args) {
        HashedWheelTimerTest.MyTimerTask myTimerTask = new HashedWheelTimerTest.MyTimerTask(true);
        Timer timer = new HashedWheelTimer();
        // 时间轮，5秒执行一次
        timer.newTimeout(myTimerTask, 5, TimeUnit.SECONDS);
        int i = 1;
        while (myTimerTask.flag) {
            try {

                Thread.sleep(1000);

            } catch (InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }
            System.out.println(i + "秒过去了");

            i++;
        }
    }
}
